package demo.java.lang.management.jvm;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import demo.java.lang.management.vo.JavaProcess;
import demo.java.lang.management.vo.StartupInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.management.ClassLoadingMXBean;
import java.lang.management.CompilationMXBean;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
import java.util.List;

public class JVM {

    private static Logger logger = LoggerFactory.getLogger(JVM.class);

    private StartupInfoCollector startupInfoCollector;
    private CpuRateCollector cpuRateCollector;
    private MemoryPoolCollector memoryPoolCollector;
    private ThreadingCollector threadingCollector;
    private GarbageCollector garbageCollector;
    private ClassLoadingCollector classLoadingCollector;
    private ProcessStatCollector processStatCollector;

    public JVM() {
        RuntimeMXBean Runtime = ManagementFactory.getRuntimeMXBean();
        ClassLoadingMXBean ClassLoading = ManagementFactory.getClassLoadingMXBean();
        CompilationMXBean Compilation = ManagementFactory.getCompilationMXBean();
        OperatingSystemMXBean OS = ManagementFactory.getOperatingSystemMXBean();
        ThreadMXBean Thread = ManagementFactory.getThreadMXBean();
        List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans();
        List<GarbageCollectorMXBean> garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans();

        this.startupInfoCollector = new StartupInfoCollector(Runtime, OS);
        this.cpuRateCollector = new CpuRateCollector((com.sun.management.OperatingSystemMXBean) OS, Runtime);
        this.memoryPoolCollector = new MemoryPoolCollector(memoryPoolMXBeans);
        this.threadingCollector = new ThreadingCollector(Thread);
        this.garbageCollector = new GarbageCollector(garbageCollectorMXBeans);
        this.classLoadingCollector = new ClassLoadingCollector(ClassLoading, Compilation);
        this.processStatCollector = new ProcessStatCollector(threadingCollector, cpuRateCollector, OS, Runtime);
    }

    public StartupInfo getStaticPartJavaProcess() {
        return startupInfoCollector.collect();
    }

    public JavaProcess getDynamicPartJavaProcess() {
        JavaProcess process = new JavaProcess();
        process.setTheadInfos(threadingCollector.collect());

        process.setMemoryPools(memoryPoolCollector.collect());
        process.setGarbageCollectorInfos(garbageCollector.collect());
        process.setClassLoading(classLoadingCollector.collect());
        process.setProcessStat(processStatCollector.collect());

        return process;
    }

    public JavaProcess getJavaProcess() {
        JavaProcess process = getDynamicPartJavaProcess();
        process.setStartupInfo(getStaticPartJavaProcess());

        return process;
    }

    public String dump() {
        try {
            return JSON.toJSONString(getJavaProcess(), SerializerFeature.PrettyFormat);
        } catch (Exception e) {
            logger.error("dump jvminfo error,please send xdcs team", e);
        }
        return null;

    }
}
